﻿window.xcookiekeys = function () {
    /// <summary>An auxiliar function to return all cookie keys inside the document.</summary>
    var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
    for (var nIdx = 0; nIdx < aKeys.length; nIdx++) { aKeys[nIdx] = unescape(aKeys[nIdx]); }
    return aKeys;
};

window.xcookievalues = function () {
    /// <summary>An auxiliar function to determines if the browser supports and activate the cookies feature.</summary>
    var result = new Array();
    var keys = window.xcookiekeys();
    for (var i = 0; i < keys.length; i++) { result.push(document.cookies.getValue(keys[i])); }
    return result;
}

window.xcookieenabled = function () {
    /// <summary>An auxiliar function to return all cookie values inside the document.</summary>
    if (navigator.cookieEnabled) return true;
    var testKey = "cookietest-jscookit";
    document.cookies.save(new DocumentCookie(testKey, "itworks"));
    var result = document.cookies.hasKey(testKey) && document.cookies.getValue(testKey) === "itworks";
    document.cookies.remove("cookietest-jscookit");
    return result;
}

var DocumentCookie = function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
    /// <param name="sKey" type="String">The name of the cookie.</param>
    /// <param name="sValue" type="String">The value of the cookie.</param>
    /// <param name="vEnd" type="String">The max-age in seconds (e.g. 31536e3 for a year, Infinity for a never-expires cookie) or the expires date in GMTString format or as Date object; if not specified it will expire at the end of session. [Type: number(finite or Infinity),string,Date object or null].</param>
    /// <param name="sPath" type="String">E.g., "/", "/mydir"; if not specified, defaults to the current path of the current document location.</param>
    /// <param name="sDomain" type="String">E.g., "example.com", ".example.com" (includes all subdomains) or "subdomain.example.com"; if not specified, defaults to the host portion of the current document location.</param>
    /// <param name="bSecure" type="String">The cookie will be transmitted only over secure protocol as https.</param>

    /// <field name="Key" type="String">The name of the cookie.</field>
    this.Key = sKey;
    /// <field name="Value" type="String">The value of the cookie.</field>
    this.Value = sValue;
    /// <field name="Expiration" type="Object">The max-age in seconds (e.g. 31536e3 for a year, Infinity for a never-expires cookie) or the expires date in GMTString format or as Date object; if not specified it will expire at the end of session. [Type: number(finite or Infinity),string,Date object or null]</field>
    this.Expiration = vEnd;
    /// <field name="Path" type="String">E.g., "/", "/mydir"; if not specified, defaults to the current path of the current document location.</field>
    this.Path = sPath;
    /// <field name="Domain" type="String">E.g., "example.com", ".example.com" (includes all subdomains) or "subdomain.example.com"; if not specified, defaults to the host portion of the current document location.</field>
    this.Domain = sDomain;
    /// <field name="IsSecure" type="Boolean">The cookie will be transmitted only over secure protocol as https.</field>
    this.IsSecure = bSecure;
};

document.cookies = {
    /// <field name="Keys" type="Array">An array that contains all the cookie keys of the document.</field>
    Keys: window.xcookiekeys(),
    /// <field name="Count" type="String">The number of all the cookie keys of the document.</field>
    Count: window.xcookiekeys().length,
    /// <field name="Keys" type="Array">An array that contains all the cookie values of the document.</field>
    Values: window.xcookievalues(),
    /// <field name="Enabled" type="Boolean">Determines if the browser supports and activate the cookies feature.</field>
    Enabled: window.xcookieenabled()
};

document.cookies.compareValue = function (sKey, sValue) {
    /// <summary>Checks whether a cookie's value is equal to another value.</summary>
    /// <param name="sKey" type="String">Key of the cookie.</param>
    /// <param name="sValue" type="String">Value to check with the cookie.</param>
    /// <returns type="Boolean">True: the cookie's value is equal to the passed value. | False: the cookie's value is not equal to the passed value.</returns>
    if (document.cookies.hasKey(sKey) && document.cookies.getValue(sKey) == sValue) {
        return true;
    }
    return false;
}

document.cookies.clear = function () {
    /// <summary> Clear all cookies of the current document.</summary>
    var i;
    for (i = 0; i < document.cookies.Keys.length; i++) {
        document.cookies.removeCookie(document.cookies.Keys[i]);
    }
};

document.cookies.findKeys = function (sValue) {
    var collection = document.cookies.getKeyAndValues();
    var result = new Array();
    for (var i = 0; i < collection.length; i++) {
        if (collection[i].Value === sValue) result.push(collection[i].Key);
    }
    return result;
};

document.cookies.getKeyAndValues = function () {
    var result = new Array();
    for (var i = 0; i < document.cookies.Keys.length; i++) {
        var key = document.cookies.Keys[i];
        result.push(new DocumentCookie(key, document.cookies.getValue(key)));
    }
    return result;
};

document.cookies.getValue = function (sKey) {
    /// <summary>Gets a value of a cookie, given a specified key.</summary>
    /// <param name="sKey" type="String">Key of the cookie.</param>
    /// <returns type="Number">The cookie's value.</returns>
    return unescape(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
};

document.cookies.hasKey = function (sKey) {
    /// <summary>Checks if the document's cookies has a cookie with the specified key.</summary>
    /// <param name="sKey" type="String">Key of the cookie.</param>
    /// <returns type="Boolean">True: the document has a cookie named as the specified key. | False: the document doesn't have a cookie named as the specified key.</returns>
    return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
};

document.cookies.remove = function (sKey) {
    /// <summary>Removes a cookie with the specified key.</summary>
    /// <param name="sKey" type="String">Key of the cookie.</param>
    /// <returns type="Boolean">True: if the cookie was removed successfuly. | False: if the cookie was not removed.</returns>
    if (!sKey || !document.cookies.hasKey(sKey)) { return false; }
    document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
    return true;
};

document.cookies.save = function (objCookie) {
    /// <summary>Saves a cookie value to the document and set its options.</summary>
    /// <param name="objCookie" type="DocumentCookie">DocumentCookie object.</param>
    if (!objCookie.Key || /^(?:expires|max\-age|path|domain|secure)$/i.test(objCookie.Key)) { return false; }
    var sExpires = "";
    if (objCookie.Expiration) {
        switch (objCookie.Expiration.constructor) {
            case Number:
                sExpires = objCookie.Expiration === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + objCookie.Expiration;
                break;
            case String:
                sExpires = "; expires=" + objCookie.Expiration;
                break;
            case Date:
                sExpires = "; expires=" + objCookie.Expiration.toGMTString();
                break;
        }
    }
    document.cookie = escape(objCookie.Key) + "=" + escape(objCookie.Value) + sExpires + (objCookie.Domain ? "; domain=" + objCookie.Domain : "") + (objCookie.Path ? "; path=" + objCookie.Path : "") + (objCookie.IsSecure ? "; secure" : "");
    return true;
};

//document.cookies.setCookieValue = function (sKey, sValue, vEnd) {
//    /// <summary>Sets a cookie value.</summary>
//    /// <param name="sKey" type="String">Key of the cookie.</param>
//    /// <param name="sValue" type="String">Value to set the cookie.</param>
//    /// <param name="vEnd" type="Object" optional="true">Key of the cookie.</param>
//    document.cookies.save(new DocumentCookie(sKey, sValue, sEnd));
//};